package algo3.vista;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.FileInputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;

import algo3.modelo.Direccion;
import algo3.modelo.Juego;
import algo3.modelo.Posicion;
import algo3.modelo.armas.*;
import algo3.modelo.barcos.*;
import algo3.vista.armas.ReflexionVistaArma;
import algo3.vista.armas.VistaArma;
import fiuba.algo3.titiritero.dibujables.SuperficiePanel;
import fiuba.algo3.titiritero.modelo.GameLoop;
import fiuba.algo3.titiritero.modelo.SuperficieDeDibujo;

public class VentanaPrincipal {

	private JFrame frame;
	private GameLoop gameLoop;
	int TABLERO_FILAS = 10;
	int TABLERO_COLUMNAS = 10;
	int PUNTAJE_INICIAL = 10000;
	int PUNTAJE_PERDIDO_POR_TURNO = 10;
	Juego juego;
	VisorPuntaje visorPuntaje;
	private Class<? extends Mina> minaSeleccionada = MinaSubmarinaPorContacto.class;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					VentanaPrincipal window = new VentanaPrincipal();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public VentanaPrincipal() {
		try {
			initialize();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * Initialize the contents of the frame.
	 * @throws IOException 
	 */
	private void initialize() throws IOException {
		frame = new JFrame();
		frame.setForeground(new Color(0, 0, 0));
		frame.setBounds(100, 100, 550, 475);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);
		frame.setTitle("  BATALLA NAVALGO  -  Algoritmos y Programacion III  -  TP2  1C/2013  -  FIUBA");
		
		JButton btnIniciar = this.addBotonIniciar();
		
		JButton btnDetener = this.addBotonDetener();
		
		JPanel panel = this.addSuperficiePanel();
		
		this.addGrupoDeBotones();
		
		this.gameLoop = new GameLoop((SuperficieDeDibujo) panel);
		
		this.inicializarModelo();
		
		this.addMouseListener(panel);
		
		this.addKeyListener();

		this.setComponentsFocus(btnIniciar, btnDetener);

	}

	private void inicializarModelo() throws IOException  {
		juego = new Juego(TABLERO_COLUMNAS, TABLERO_FILAS);
		SistemaCoordenadas.setTamanioTablero(TABLERO_COLUMNAS, TABLERO_FILAS);
		Barco barco1 = new Lancha(new Posicion(1, 1), Direccion.DERECHA, Direccion.DERECHA);
		Barco barco2 = new Destructor(new Posicion(5, 5), Direccion.DIAG_DERECHA_ABAJO, Direccion.DERECHA);
		Barco barco3 = new PortaAviones(new Posicion(3, 3), Direccion.DIAG_IZQUIERDA_ABAJO, Direccion.DERECHA);
		Barco barco4 = new Buque(new Posicion(1, 7), Direccion.ARRIBA, Direccion.DERECHA);
		Barco barco5 = new RompeHielos(new Posicion(6, 8), Direccion.ABAJO, Direccion.DERECHA);
		Barco barco6 = new Lancha(new Posicion(1, 7), Direccion.DIAG_DERECHA_ABAJO, Direccion.DERECHA);
		Barco barco7 = new Destructor(new Posicion(1, 8), Direccion.DERECHA, Direccion.DERECHA);		
		juego.agregarBarco(barco1);
		juego.agregarBarco(barco2);
		juego.agregarBarco(barco3);
		juego.agregarBarco(barco4);
		juego.agregarBarco(barco5);
		juego.agregarBarco(barco6);
		juego.agregarBarco(barco7);
				
		this.gameLoop.agregar(new VistaBarco(barco1));
		this.gameLoop.agregar(new VistaBarco(barco2));
		this.gameLoop.agregar(new VistaBarco(barco3));
		this.gameLoop.agregar(new VistaBarco(barco4));
		this.gameLoop.agregar(new VistaBarco(barco5));
		this.gameLoop.agregar(new VistaBarco(barco6));
		this.gameLoop.agregar(new VistaBarco(barco7));
				
		this.gameLoop.agregar(this.addVisorPuntaje());
		
		this.gameLoop.agregar(juego);
		
		this.gameLoop.agregar(new ObservadorFinJuego(gameLoop, visorPuntaje, juego));
		
	}

	private void setComponentsFocus(JButton btnIniciar, JButton btnDetener) {
		frame.setFocusable(true);
		btnDetener.setFocusable(false);
		btnIniciar.setFocusable(false);
	}

	private void addKeyListener() {
		frame.addKeyListener(new KeyListener(
				) {
			
			@Override
			public void keyTyped(KeyEvent arg0) {
				System.out.println("Key pressed");
			}
			
			@Override
			public void keyReleased(KeyEvent arg0) {
			}
			
			@Override
			public void keyPressed(KeyEvent arg0) {
				System.out.println("Ping");
			}  
			 	
		});
	}

	private void addMouseListener(JPanel panel) {
		
		panel.addMouseListener(new MouseAdapter() {	
			@Override
			public void mousePressed(MouseEvent event) {
				if (SwingUtilities.isLeftMouseButton(event)){
					Posicion pos = SistemaCoordenadas.posicionDePixel(event.getX(), event.getY());
					System.out.println(String.format("left mouse button: X%d, Y%d, posicion: %d %d", event.getX(), event.getY(), pos.getColumna(), pos.getFila()));	
					agregarArma("DisparoConvencional",pos);
				}
				if (SwingUtilities.isRightMouseButton(event)){
					Posicion pos = SistemaCoordenadas.posicionDePixel(event.getX(), event.getY());
					System.out.println(String.format("rigth mouse button: X%d, Y%d, posicion: %d %d", event.getX(), event.getY(), pos.getColumna(), pos.getFila()));	
					agregarArma(minaSeleccionada.getSimpleName(), pos);
				}
			}
		});
	}
	
	private void agregarArma(String nombreArma, Posicion pos) {
		
		Arma arma = ReflexionDeArma.obtenerArmaPorReflexion(nombreArma, pos);
		VistaArma vista = ReflexionVistaArma.obtenerVistaArmaPorReflexion("Vista"+nombreArma,arma);
		if(visorPuntaje.getPuntaje() >= arma.getCosto()){
			visorPuntaje.descontarCostoDelArma(arma.getCosto());
			juego.agregarArma(arma);
			gameLoop.agregar(vista);
		}
	}
	
	private void setMinaSeleccionada(Class<? extends Mina> mina){
		this.minaSeleccionada = mina;
	}

	private JPanel addSuperficiePanel() throws IOException {
		SuperficiePanel panel = new SuperficiePanelConFondo();
		FileInputStream inStream = new FileInputStream("resources/water.jpg");
		panel.setImagen(ImageIO.read(inStream));
		panel.setBounds(120, 53, SistemaCoordenadas.getTamanioCelda()*TABLERO_FILAS, SistemaCoordenadas.getTamanioCelda()*TABLERO_COLUMNAS);
		frame.getContentPane().add(panel);
		
		return panel;
	}

	private JButton addBotonDetener() {
		JButton btnDetener = new JButton("Detener");
		btnDetener.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				gameLoop.detenerEjecucion();
			}
		});
		btnDetener.setBounds(420, 16, 92, 25);
		frame.getContentPane().add(btnDetener);
		return btnDetener;
	}

	private JButton addBotonIniciar() {
		JButton btnIniciar = new JButton("Iniciar");
		btnIniciar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				gameLoop.iniciarEjecucion();
			}
		});
		btnIniciar.setBounds(42, 16, 77, 25);
		frame.getContentPane().add(btnIniciar);
		return btnIniciar;
	}
	
	private VisorPuntaje addVisorPuntaje() {
		visorPuntaje = new VisorPuntaje(14, PUNTAJE_INICIAL, PUNTAJE_PERDIDO_POR_TURNO);
		visorPuntaje.setBounds(120, 400, 120, 25);
		visorPuntaje.setText(String.format("Puntos: %d", PUNTAJE_INICIAL));
		frame.getContentPane().add(visorPuntaje);
		return visorPuntaje;
	}	

	private void addGrupoDeBotones() {
		ButtonGroup grupoBotones = new ButtonGroup();		
		JRadioButton minaPorContacto = new JRadioButton("mina x contacto", true);
        grupoBotones.add(minaPorContacto);
        frame.getContentPane().add(minaPorContacto);
        minaPorContacto.setBounds(42, 360, 125, 25);
        minaPorContacto.addItemListener(new ItemListener() {
        	public void itemStateChanged(ItemEvent evento) {
        		setMinaSeleccionada(MinaSubmarinaPorContacto.class);
			}
        });      	        
        JRadioButton minaPuntualConRetardo = new JRadioButton("mina puntual", false);
        grupoBotones.add(minaPuntualConRetardo);
        frame.getContentPane().add(minaPuntualConRetardo);
        minaPuntualConRetardo.setBounds(170, 360, 100, 25);
        minaPuntualConRetardo.addItemListener(new ItemListener() {
        	public void itemStateChanged(ItemEvent evento) {
        		setMinaSeleccionada(MinaSubmarinaPuntualConRetardo.class);
			}
        });      	
        JRadioButton minaDobleConRetardo = new JRadioButton("mina doble", false);
        grupoBotones.add(minaDobleConRetardo);
        frame.getContentPane().add(minaDobleConRetardo);
        minaDobleConRetardo.setBounds(280, 360, 100, 25);
        minaDobleConRetardo.addItemListener(new ItemListener() {
        	public void itemStateChanged(ItemEvent evento) {
        		setMinaSeleccionada(MinaSubmarinaDobleConRetardo.class);
			}
        });

        JRadioButton minaTripleConRetardo = new JRadioButton("mina triple", false);
        grupoBotones.add(minaTripleConRetardo);
        frame.getContentPane().add(minaTripleConRetardo);
        minaTripleConRetardo.setBounds(385, 360, 100, 25);
        minaTripleConRetardo.addItemListener(new ItemListener() {
        	public void itemStateChanged(ItemEvent evento) {
        		setMinaSeleccionada(MinaSubmarinaTripleConRetardo.class);
			}
        });      	
		}
}
